/*
* citys-api.js 省市数据操作
* author:devin87@qq.com  
* update:2023/08/21 17:38
*/
(function (undefined) {
    var list_prov = dataCitys["0"],
        map_prov = {},

        map_prov_citys = {},

        list_city = [],
        map_city = {},

        I_NOT_FOUND = -1,
        PROV_OTHER = "其它国家及地区";

    var map_addr_by_name = {
        '海南州': '青海省海南州',
        '吉林市': '吉林省吉林市'
    };

    /**
     * 格式化省份名称 eg:湖北省 => 湖北
     * @param {string} prov 
     */
    function formatProv(prov) {
        if (prov.length <= 2) return prov;
        return prov.replace(/[省市]$|国家及地区$/g, '');
    }

    /**
     * 格式化城市名称 eg:武汉市 => 武汉
     * @param {string} city 
     */
    function formatCity(city) {
        var name = city.length <= 2 ? city : city.replace(/国家及地区$|特别行政区$|地区$|[州市盟县]$/g, '');
        return name.replace('襄樊', '襄阳').replace('思茅', '普洱').replace('克州', '克孜勒州');
    }

    //数据初始化
    function init() {
        for (var i = 0, len = list_prov.length; i < len; i++) {
            var prov = list_prov[i];
            map_prov[formatProv(prov)] = i;
            map_prov_citys[i] = [];

            var citys = dataCitys["0_" + i] || [];
            for (var j = 0, len2 = citys.length; j < len2; j++) {
                var dataCity = { pid: i, prov: prov, cid: j, city: citys[j] };

                list_city.push(dataCity);
                map_city[formatCity(citys[j])] = dataCity;
                map_prov_citys[i].push(dataCity);
            }
        }
    }

    init();

    /**
     * 根据省份编号获取城市对象列表 => [{pid,prov,cid,city}]
     * @param {number} pid 省份编号 
     */
    function getDataCitys(pid) {
        return map_prov_citys[pid];
    }

    /**
     * 根据省份编号获取城市列表
     * @param {number} pid 省份编号 
     */
    function getCitys(pid) {
        return dataCitys["0_" + pid];
    }

    /**
     * 获取省份编号
     * @param {string} prov 省份名称
     */
    function getPid(prov) {
        var pid = map_prov[formatProv(prov)];
        return pid != undefined ? pid : I_NOT_FOUND;
    }

    /**
     * 获取城市对象
     * @param {string} city 城市名称
     */
    function getDataCity(city) {
        return map_city[formatCity(city)];
    }

    /**
     * 获取城市编号
     * @param {string} prov 省份名称
     * @param {string} city 城市名称
     */
    function getCid(prov, city) {
        if (city == undefined) city = prov;

        var data = getDataCity(city);
        return data ? data.cid : I_NOT_FOUND;
    }

    /**
     * 获取省份名称
     * @param {number} pid 省份编号
     */
    function getProv(pid) {
        return list_prov[pid];
    }

    /**
     * 获取城市名称
     * @param {number} pid 省份编号
     * @param {number} cid 城市编号
     */
    function getCity(pid, cid) {
        var citys = getCitys(pid);

        return citys ? citys[cid] : undefined;
    }

    /**
     * 查找匹配的省份编号,若未匹配到映射,则会在所有省份中查找
     * @param {string} prov 省份名称
     * @param {boolean} is_full_match 为true则不在列表中查找,直接返回结果
     */
    function findPid(prov, is_full_match) {
        if (!prov) return I_NOT_FOUND;

        var pid = getPid(prov);
        if (pid != I_NOT_FOUND) return pid;
        if (is_full_match) return I_NOT_FOUND;

        for (var i = 0, len = list_prov.length; i < len; i++) {
            if (prov.indexOf(formatProv(list_prov[i])) != -1) return i;
        }

        return I_NOT_FOUND;
    }

    /**
     * 根据城市名称查找城市对象
     * @param {string} city 城市名称或代码
     * @param {Array.<object>} citys 城市列表 eg: ['武汉'] | [{cid:0,city:'武汉'}]
     */
    function findCityInList(city, citys) {
        for (var i = 0, len = citys.length; i < len; i++) {
            var data = citys[i];
            if (data.city) {
                if (city.indexOf(formatCity(data.city)) != -1) return data;
            } else if (typeof data == 'string') {
                if (city.indexOf(formatCity(data)) != -1) return { cid: i, city: data };
            }
        }
    }

    /**
     * 查找匹配的城市,若未匹配到映射,则会在所有城市中查找
     * @param {string} city 城市名称
     * @param {Array.<object>|undefined} citys 城市列表,为空则查找所有城市
     * @param {boolean} is_full_match 为true则不在城市列表中查找,直接返回结果
     */
    function findCity(city, citys, is_full_match) {
        if (!city) return;

        city = formatCity(city).replace('襄樊', '襄阳').replace('思茅', '普洱');

        //若指定了城市列表，则优先在指定的城市列表中查找
        if (citys) return findCityInList(city, citys);

        var data_city = getDataCity(city);
        if (data_city || is_full_match) return data_city;

        return findCityInList(city, list_city);
    }

    /**
     * 查找匹配的城市,若未匹配到映射且未指定citys,则会在所有城市中查找
     * @param {string} city 城市名称
     * @param {Array.<object>|undefined} citys 城市列表,为空则查找所有城市
     * @param {boolean} is_full_match 为true则不在城市列表中查找,直接返回结果
     */
    function findCid(city, citys, is_full_match) {
        var data = findCity(city, citys);
        return data ? data.cid : I_NOT_FOUND;
    }

    /**
     * 查找省市数据
     * @param {string} prov 省份
     * @param {string} city 城市
     */
    function findData(prov, city) {
        var result = {}, citys;

        if (prov) {
            var pid = findPid(prov, false);
            if (pid != undefined && pid != I_NOT_FOUND) {
                result.pid = pid;
                result.prov = getProv(pid);

                citys = getDataCitys(pid);
            }
        }

        if (city) {
            var data_city = findCity(city, citys);
            if (data_city) {
                if (data_city.pid != undefined) {
                    result.pid = data_city.pid;
                    result.prov = getProv(result.pid);
                }

                result.cid = data_city.cid;
                result.city = data_city.city;
            }
        }

        return result;
    }

    /**
     * 查找省市数据
     * @param {string} addr 省市地址 eg:湖北武汉 联通|湖北省武汉市|湖北武汉|湖北|武汉|武汉武汉
     * @param {boolean} is_full_match 是否完整匹配 eg: 海南州  => 青海省海南州
     */
    function find(addr, is_full_match) {
        var gs = (addr + '').split(' '),
            geo = gs[0] || '';

        if (!geo) return {};

        geo = (map_addr_by_name[geo] || geo) + '';

        var i = geo.indexOf('省');
        if (i > 0) return findData(geo.slice(0, i), geo.slice(i + 1));

        var result = {},
            pid = is_full_match ? map_prov[formatProv(geo)] : findPid(geo),
            citys;

        if (pid != undefined && pid != I_NOT_FOUND) {
            result.pid = pid;
            result.prov = getProv(pid);

            if (is_full_match || formatProv(result.prov) == formatProv(geo)) return result;

            citys = getDataCitys(pid);
        }

        var data_city = findCity(geo, citys, is_full_match);

        if (data_city) {
            if (data_city.pid != undefined) {
                result.pid = data_city.pid;
                result.prov = getProv(result.pid);
            }

            result.cid = data_city.cid;
            result.city = data_city.city;
        }

        return result;
    }

    /**
     * 格式化区域 eg: 武汉市 => [{prov:'湖北省',city:'武汉市'}]
     * @param {string} areas 区域,多个之间用空格分隔 eg: 海南省 包头市 海南州
     */
    function formatAreas(areas) {
        if (!areas || areas == '*') return [];

        var list_area = areas.split(' '), map_prov = {}, list_prov = [], list_city = [];
        for (var i = 0, len = list_area.length; i < len; i++) {
            var area = list_area[i];
            if (!area) continue;

            var sc = find(area, true);

            //没有匹配的省份或城市
            if (sc.pid == undefined) continue;

            //省份
            if (sc.cid == undefined) {
                if (!map_prov[sc.prov]) {
                    list_prov.push(sc);
                    map_prov[sc.prov] = true;
                }
                continue;
            }

            //城市
            list_city.push(sc);
        }

        //过滤省份已存在的城市 eg: '湖北,武汉,孝感,三亚' => '湖北,三亚'
        list_city = list_city.filter(function (sc) {
            return !map_prov[sc.prov];
        });

        return list_prov.concat(list_city);
    }

    /**
     * 根据省份或城市筛选区域。若返回空数组则表示未筛选；若返回undefined则表示未匹配到数据；正常则返回 [{pid,prov,cid,city}]
     * @param {string} areas 区域,多个之间用空格分隔 eg: 海南省 包头市 海南州
     * @param {string} prov 省份
     * @param {string} city 城市,为空则根据省份筛选
     */
    function filterAreas(areas, prov, city) {
        var list_area = formatAreas(areas);
        if (!prov) return list_area;

        var sc = findData(prov, city);
        if (sc.pid == undefined) return undefined;

        if (list_area.length <= 0) {
            return [sc];
        }

        var citys = [];

        for (var i = 0, len = list_area.length; i < len; i++) {
            var area = list_area[i];
            if (!area || area.pid != sc.pid) continue;

            if (sc.cid == undefined) {
                if (area.cid == undefined) return [sc];
                citys.push(area);
            } else {
                if (area.cid == undefined || area.cid == sc.cid) return [sc];
            }
        }

        return citys.length > 0 ? citys : undefined;
    }

    /**
     * 检查省份或城市是否在区域内
     * @param {string} areas 区域,多个之间用空格分隔 eg: 海南省 包头市 海南州
     * @param {number} pid 省份ID
     * @param {number} cid 城市ID,为空则检查省份是否在区域内
     * @param {boolean} skipCid 是否忽略城市ID比较
     */
    function checkInAreas(areas, pid, cid, skipCid) {
        if (!areas || areas == '*') return true;
        if (pid == undefined) return false;

        var list_area = (areas + '').split(' ');
        for (var i = 0, len = list_area.length; i < len; i++) {
            var area = list_area[i].trim();
            if (!area) continue;

            var sc = find(area, true);
            //没有匹配的省份或城市
            if (sc.pid == undefined) continue;

            if (sc.pid == pid) {
                if (skipCid) return true;

                if (cid == undefined) {
                    if (sc.cid == undefined) return true;
                } else {
                    //area是省份或相同的城市
                    if (sc.cid == undefined || sc.cid == cid) return true;
                }
            }
        }

        return false;
    }

    var DC = {
        //所有省份
        provs: list_prov,
        //所有城市
        citys: list_city,

        mapProv: map_prov,
        mapCity: map_city,

        getDataCitys: getDataCitys,
        getCitys: getCitys,

        getPid: getPid,
        getCid: getCid,

        getProv: getProv,
        getCity: getCity,

        formatProv: formatProv,
        formatCity: formatCity,

        findPid: findPid,
        findCid: findCid,
        findCity: findCity,
        findData: findData,

        find: find,

        formatAreas: formatAreas,
        filterAreas: filterAreas,
        checkInAreas: checkInAreas,

        OTHER: PROV_OTHER
    };

    if (typeof module === 'object' && typeof module.exports === 'object') module.exports = DC;

    if (typeof window !== 'undefined') window.DC = DC;
})();